#pragma once
#include <sstream>

namespace DirectUI
{

#define BEGIN_UI_PROPERTY_MAP(PropertyNameEnum)	\
protected:	\
	std::vector<CUIObjectPtr<IUIProperty>>	m_vPropertys;	\
	std::map<CString, int>		m_mapPropertyName;	\
	virtual IUIProperty*	GetProperty(LPCTSTR lpName)	\
	{ \
		std::map<CString, int>::iterator pit =  m_mapPropertyName.find(lpName);	\
		if ( pit == m_mapPropertyName.end() )	\
			return NULL;	\
		return m_vPropertys[pit->second];	\
	}	\
public:	\
	virtual BOOL GetUIElementNameEnum(LPCTSTR lpszName, int& e)	\
	{ \
		std::map<CString, int>::iterator pit = m_mapPropertyName.find(lpszName);	\
		if ( pit != m_mapPropertyName.end() )	\
		{ \
			e = pit->second;	\
			return TRUE;	\
		}	\
		return FALSE;	\
	}	\
	virtual IUIProperty*	GetProperty(PropertyNameEnum name) { return m_vPropertys[name]; }	\
protected:	\
	void ProperyInfoInit()	\
	{	\
		m_vPropertys.resize(UINAMEMAX);

#define UI_PROPERTY(name, valType)	\
		m_vPropertys[name] = new CUIProperty(name, L#name, valType, this);	\
		m_mapPropertyName[L#name] = name;

#define END_UI_PROPERTY_MAP	\
	}

	class CUIProperty
		: public CUINoAggregateObjectImplHelper<IUIProperty, CUIProperty, IUIProperty>
	{
		DECLARE_CLASS(CUIProperty, Property)
	public:
		CUIProperty() { }
		CUIProperty(int NameEnum, LPCTSTR lpPropertyName, UIObjectType type, IUIObject* lpObj)
			: m_NameEnum(NameEnum), m_szName(lpPropertyName), m_ValObjectType(type), m_spTargetObj(lpObj)
		{

		}
		~CUIProperty()
		{

		}
	public:
		static void ParseAttribute(xml_attribute& attr, IUIProperty* lpProperty);
		static void TimelineParseAttribute(xml_attribute& attr, IUIProperty* lpProperty);

		virtual	wchar_t*			GetPropertyName() { return (wchar_t*)m_szName.c_str(); }
		virtual	__int32				GetPropertyNameEnum() { return m_NameEnum; }
		virtual	IUIObject*			GetValue() { return m_spValue; }
		virtual	UIObjectType		GetValueType() { return m_ValObjectType; }

		virtual bool				GetBOOLValue();
		virtual void				SetBOOLValue(bool val);
		virtual __int32				GetIntValue();
		virtual void				SetIntValue(__int32 val);
		virtual UIRect				GetRectValue();
		virtual void				SetRectValue( UIRect val );
		virtual float				GetFloatValue();
		virtual void				SetFloatValue( float val );
		virtual double				GetDoubleValue();
		virtual void				SetDoubleValue( double val );
		virtual UICOLOR				GetColorValue();
		virtual void				SetColorValue( UICOLOR val );
		virtual wchar_t*			GetStringValue();
		virtual void				SetStringValue( wchar_t* val );
		virtual UIAlign				GetAlignValue();
		virtual void				SetAlignValue( UIAlign val );
		virtual UITIMESPAN			GetTimeSpanValue();
		virtual void				SetTimeSpanValue( UITIMESPAN val );

	private:
		void						EnsureValueExist();
		virtual void				PropertyChanged();
		virtual IUIPropertyEvent*	GetUIPropertyEvent();

		__int32						m_NameEnum;
		UIObjectType				m_ValObjectType;
		std::wstring				m_szName;
		CUIObjectPtr<IUIObject>		m_spValue;
		CUIObjectPtr<IUIObject>		m_spTargetObj;
	};
}
